#include "stm32f4xx.h"
#include "init.h"

void User_InitUsart1(uint32_t baudRate){
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
    
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
    
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    USART_InitTypeDef USART_InitStruct;
    USART_StructInit(&USART_InitStruct);
    USART_InitStruct.USART_BaudRate = baudRate;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStruct);
    
    USART_ClearFlag(USART1, USART_FLAG_RXNE);
    USART_Cmd(USART1, ENABLE);
}

Device_TTP223 User_InitTTP223_1(void){
    Device_TTP223 dv;
    dv.gpioPort = GPIOB;
    dv.gpioPin = GPIO_Pin_0;
    dv.lastState = 0x00;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    NVIC_InitTypeDef   NVIC_InitStructure;
    EXTI_InitTypeDef   EXTI_InitStructure;

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    return dv;
}

Device_PressureSensor User_InitPressureSensor_PA5_ADC1(void){
    extern uint8_t programState_ADC_Initialized;
    Device_PressureSensor dv;
    dv.adcPort = ADC1;
    dv.gpioPort = GPIOA;
    dv.gpioPin = GPIO_Pin_5;
    dv.adcChannel = ADC_Channel_5;
    dv.lastData = 0;
    
    GPIO_InitTypeDef  GPIO_InitStructure; // 配置结构体

    RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = dv.gpioPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(dv.gpioPort, &GPIO_InitStructure);

    if(programState_ADC_Initialized == 0x00){
        ADC_CommonInitTypeDef ADC_CommonInitStruct;
        ADC_DeInit();
        ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
        ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;
        ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;
        ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
        ADC_CommonInit(&ADC_CommonInitStruct);
    }
    
    ADC_InitTypeDef ADC_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
    ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
    ADC_InitStruct.ADC_NbrOfConversion=1;
    ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;

    ADC_Init(dv.adcPort, &ADC_InitStruct);
    ADC_Cmd(dv.adcPort, ENABLE);
    
    return dv;
}

Device_LED User_InitLED_B2(void){ 
    Device_LED dv;
    
    dv.bitValWhenStateIsOn = Bit_SET;
    dv.GPIO_Port = GPIOB;
    dv.GPIO_Pin = GPIO_Pin_2;
    dv.state = LED_OFF;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Pin = dv.GPIO_Pin;
    
    GPIO_Init(dv.GPIO_Port, &GPIO_InitStruct);
    
    BSP_LED_SyncState(&dv);
    return dv;
}

/* 这里各个资源的对应关系没有经过考察，只是做个步骤参考 */
Device_DMA_ADCToPWM User_InitADC2PWM_PA3_ADC1_To_PB3_PWM_TIM1(uint16_t* bufAddr){
    Device_DMA_ADCToPWM dv;
    dv.ADC_Port =           ADC1;
    dv.ADC_Channel =        ADC_Channel_3;
    dv.DMA_BufAddr =        bufAddr;
    dv.PWM_TIM_Period =     3999;
    dv.PWM_TIM_Port =       TIM1;
    dv.PWM_TIM_SetCompareFunc = TIM_SetCompare1;
    
    //假设占用DMA2的Stream 5
    
    // 假设PA3模拟输入，PB3为TIM1的PWM输出
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
    /*RCC_AXXPeriphClockCmd(XXX, ENABLE);*/ //激活TIM、ADC、B口PWM复用的时钟

    /* 注意复用配置 */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_TIM1);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    
    DMA_InitTypeDef DMA_InitStructure;
    
    DMA_DeInit(DMA2_Stream5);
    DMA_InitStructure.DMA_Channel = DMA_Channel_4;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)dv.ADC_Port->DR;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)bufAddr;              //DMA 存储器0地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                 //存储器到外设模式
    DMA_InitStructure.DMA_BufferSize = 1;                                   //数据传输量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        //外设非增量模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 //存储器增量模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         //存储器数据长度:8位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                           //使用普通模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                 //高等优先级
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                  //不开启FIFO模式
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;           //FIFO阈值
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;             //存储器突发单次传输
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;     //外设突发单次传输
    DMA_Init(DMA2_Stream5, &DMA_InitStructure);
    DMA_Cmd(DMA2_Stream5, ENABLE);  //使能DMA2_Stream5通道
    
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    //初始化TIM3
    TIM_TimeBaseStructure.TIM_Period =          1000U;                      //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler =       0;                          //设置用来作为TIMx时钟频率除数的预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision =   TIM_CKD_DIV1;               // 时钟分频
    TIM_TimeBaseStructure.TIM_CounterMode =     TIM_CounterMode_Up;         //TIM向上计数模式
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    
    TIM_OCInitTypeDef TIM_OCInitStructure;
    //初始化TIM1 Channel2 PWM模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //选择定时器模式:TIM脉冲宽度调制模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       //输出极性
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);                        //根据T指定的参数初始化外设TIM3 OC2
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);               //使能TIM3在CCR2上的预装载寄存器
    
    TIM_Cmd(TIM1, ENABLE);  //使能TIM1
    return dv;
}

